package com.alibaba.nacossync.extension.impl;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.util.UriComponentsBuilder;

import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.client.naming.NacosNamingService;
import com.alibaba.nacos.client.naming.core.ServerListManager;
import com.alibaba.nacos.client.naming.remote.NamingClientProxyDelegate;
import com.alibaba.nacossync.BaseServiceTest;
import com.alibaba.nacossync.constant.SkyWalkerConstants;
import com.alibaba.nacossync.extension.holder.NacosServerHolder;
import com.alibaba.nacossync.pojo.model.TaskDO;
import com.alibaba.nacossync.util.HttpUtil;

import net.minidev.json.JSONObject;

/**
 * @author paderlol
 * @date: 2019-01-12 20:58
 * @see EurekaSyncToNacosServiceImpl
 */
public class EurekaSyncToNacosServiceImplTest2 extends BaseServiceTest {
	@Autowired
	private NacosServerHolder nacosServerHolder;

	@Test
	public void t1() {
		System.out.println("tttttttttttt");
	}

	@Test
	public void testSync() throws NacosException, InterruptedException {
		TaskDO taskDO = new TaskDO();
		taskDO.setDestClusterId("DestClusterId001");
		taskDO.setNameSpace("DEV");
		taskDO.setServiceName("test_service");
		taskDO.setSourceClusterId("26d87489018c0699359068335cc90fcc");
		taskDO.setDestClusterId("0a9fc15066a6bc1da279768f55edd13c");
		taskDO.setTaskId("d0fc6a719ce6781f3335243d07cc8078");
		taskDO.setTaskStatus("SYNC");
		taskDO.setGroupName("DEFAULT_GROUP");
		NamingService destNamingService = nacosServerHolder.get(taskDO.getDestClusterId(), taskDO.getNameSpace());
		destNamingService.registerInstance(taskDO.getServiceName(), taskDO.getGroupName(),
				buildSyncInstance("192.168.38.218", 10000, taskDO));
		destNamingService.registerInstance(taskDO.getServiceName(), taskDO.getGroupName(),
				buildSyncInstance("192.168.38.218", 20000, taskDO));
		Thread.sleep(10000000);
	}

	private Instance buildSyncInstance(String ip, int port, TaskDO taskDO) {
		Instance temp = new Instance();
		temp.setIp(ip);
		temp.setPort(port);
		temp.setServiceName(taskDO.getServiceName());
		temp.setClusterName(taskDO.getServiceName());
		temp.setHealthy(true);

		Map<String, String> metaData = new HashMap<>(new ConcurrentHashMap<String, String>());
		metaData.put(SkyWalkerConstants.DEST_CLUSTERID_KEY, taskDO.getDestClusterId());
		metaData.put(SkyWalkerConstants.SYNC_SOURCE_KEY, "Eureka-DEV");
		metaData.put(SkyWalkerConstants.SOURCE_CLUSTERID_KEY, taskDO.getSourceClusterId());
		temp.setMetadata(metaData);
		return temp;
	}

	@Test
	public void testSyncByConfigUsingHttp() throws NacosException, InterruptedException, NoSuchFieldException,
			SecurityException, IllegalArgumentException, IllegalAccessException, UnsupportedEncodingException {
		TaskDO taskDO = new TaskDO();
		taskDO.setDestClusterId("DestClusterId001");
		taskDO.setNameSpace("DEV");
		taskDO.setServiceName("test_service");
		taskDO.setSourceClusterId("26d87489018c0699359068335cc90fcc");
		taskDO.setDestClusterId("0a9fc15066a6bc1da279768f55edd13c");
		taskDO.setTaskId("d0fc6a719ce6781f3335243d07cc8078");
		taskDO.setTaskStatus("SYNC");
		taskDO.setGroupName("DEFAULT_GROUP");
		NamingService destNamingService = nacosServerHolder.get(taskDO.getDestClusterId(), taskDO.getNameSpace());
		
		// 通过反射获取Nacos服务的地址
		NacosNamingService nacosNamingService = (NacosNamingService) destNamingService;
		Field clientProxyField = nacosNamingService.getClass().getDeclaredField("clientProxy");
		clientProxyField.setAccessible(true);
		NamingClientProxyDelegate clientProxyDelegate = (NamingClientProxyDelegate) clientProxyField
				.get(nacosNamingService);
		Field serverListManagerField = clientProxyDelegate.getClass().getDeclaredField("serverListManager");
		serverListManagerField.setAccessible(true);
		ServerListManager serverListManager = (ServerListManager) serverListManagerField.get(clientProxyDelegate);

		List<String> serverList = serverListManager.getServerList();
		String nacosServerUrl = serverList.get(0) + "/nacos/v1/ns/instance";
		if (!nacosServerUrl.startsWith("http")) {
			nacosServerUrl = "http://" + nacosServerUrl;
		}
		
		//组装Instance
		Instance instance = buildSyncInstance("192.168.38.218", 10000, taskDO);
		MultiValueMap<String, String> uriVariables = new LinkedMultiValueMap<>();
		uriVariables.add("ip", instance.getIp());
		uriVariables.add("port", instance.getPort()+"");
		uriVariables.add("namespaceId", "DEV");
		uriVariables.add("weight", "1");
		uriVariables.add("enabled", "true");
		uriVariables.add("healthy", "true");
		uriVariables.add("metadata", JSONObject.toJSONString(instance.getMetadata()));
		uriVariables.add("clusterName", instance.getClusterName());
		uriVariables.add("serviceName", instance.getServiceName());
		uriVariables.add("groupName", taskDO.getGroupName());
		uriVariables.add("ephemeral", "true");
		
		//发起HTTP注册请求
		UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(nacosServerUrl).queryParams(uriVariables);
		String response = HttpUtil.sendPost(builder.toUriString());
		System.out.println(response);
		
		
		instance = buildSyncInstance("192.168.38.218", 20000, taskDO);
		uriVariables = new LinkedMultiValueMap<>();
		uriVariables.add("ip", instance.getIp());
		uriVariables.add("port", instance.getPort()+"");
		uriVariables.add("namespaceId", "DEV");
		uriVariables.add("weight", "1");
		uriVariables.add("enabled", "true");
		uriVariables.add("healthy", "true");
		uriVariables.add("metadata", JSONObject.toJSONString(instance.getMetadata()));
		uriVariables.add("clusterName", instance.getClusterName());
		uriVariables.add("serviceName", instance.getServiceName());
		uriVariables.add("groupName", taskDO.getGroupName());
		uriVariables.add("ephemeral", "true");
		
		builder = UriComponentsBuilder.fromHttpUrl(nacosServerUrl).queryParams(uriVariables);
		response = HttpUtil.sendPost(builder.toUriString());
		System.out.println(response);
		//发起HTTP注册请求
		
		Thread.sleep(10000000);
	}
	
	@Test
	public void testSyncUsingHttp() throws NacosException, InterruptedException, NoSuchFieldException,
			SecurityException, IllegalArgumentException, IllegalAccessException, UnsupportedEncodingException {
		
		String nacosServerUrl="http://127.0.0.1:8848/nacos/v1/ns/instance";
		
		//组装提交的值
		MultiValueMap<String, String> uriVariables = new LinkedMultiValueMap<>();
		uriVariables.add("ip", "192.168.38.218");
		uriVariables.add("port", "10000");
		uriVariables.add("namespaceId", "DEV");
		uriVariables.add("weight", "1");
		uriVariables.add("enabled", "true");
		uriVariables.add("healthy", "true");
		uriVariables.add("metadata", "{\"preserved.register.source\": \"SPRING_CLOUD\"}");
		uriVariables.add("clusterName", "test_service");
		uriVariables.add("serviceName", "test_service");
		uriVariables.add("groupName", "DEFAULT_GROUP");
		uriVariables.add("ephemeral", "true");
		
		//发起HTTP注册请求
		UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(nacosServerUrl).queryParams(uriVariables);
		String response = HttpUtil.sendPost(builder.toUriString());
		System.out.println(response);
		
		
		//组装提交的值
		uriVariables = new LinkedMultiValueMap<>();
		uriVariables.add("ip", "192.168.38.218");
		uriVariables.add("port", "20000");
		uriVariables.add("namespaceId", "DEV");
		uriVariables.add("weight", "1");
		uriVariables.add("enabled", "true");
		uriVariables.add("healthy", "true");
		uriVariables.add("metadata", "{\"preserved.register.source\": \"SPRING_CLOUD\"}");
		uriVariables.add("clusterName", "test_service");
		uriVariables.add("serviceName", "test_service");
		uriVariables.add("groupName", "DEFAULT_GROUP");
		uriVariables.add("ephemeral", "true");
		
		builder = UriComponentsBuilder.fromHttpUrl(nacosServerUrl).queryParams(uriVariables);
		response = HttpUtil.sendPost(builder.toUriString());
		System.out.println(response);
		//发起HTTP注册请求
		
		Thread.sleep(10000000);
	}

}
